/* parse the input, from python float to c double */ if (!PyArg_ParseTuple(args, "d", &value)) return NULL; /* if the above function returns -1, an appropriate Python exception will * have been set, and the function simply returns NULL */
/* call cos from libm */ answer = cos(value);
/* construct the output from cos, from c double to python float */ return Py_BuildValue("f", answer); }
/* parse single numpy array argument */ if (!PyArg_ParseTuple(args, "O!", &PyArray_Type, &in_array)) return NULL;
/* construct the output array, like the input array */ out_array = PyArray_NewLikeArray(in_array, NPY_ANYORDER, NULL, 0); if (out_array == NULL) return NULL;
/* create the iterators */ /* TODO: this iterator API is deprecated since 1.6 * replace in favour of the new NpyIter API */ in_iter = (PyArrayIterObject *)PyArray_IterNew((PyObject*)in_array); out_iter = (PyArrayIterObject *)PyArray_IterNew(out_array); if (in_iter == NULL || out_iter == NULL) goto fail;
/* iterate over the arrays */ while (in_iter->index < in_iter->size && out_iter->index < out_iter->size) { /* get the datapointers */ double * in_dataptr = (double *)in_iter->dataptr; double * out_dataptr = (double *)out_iter->dataptr; /* cosine of input into output */ *out_dataptr = cos(*in_dataptr); /* update the iterator */ PyArray_ITER_NEXT(in_iter); PyArray_ITER_NEXT(out_iter); }
/* clean up and return the result */ Py_DECREF(in_iter); Py_DECREF(out_iter); Py_INCREF(out_array); return out_array;
/* in case bad things happen */ fail: Py_XDECREF(out_array); Py_XDECREF(in_iter); Py_XDECREF(out_iter); return NULL; }
/* define functions in module */ static PyMethodDef CosMethods[] = { {"cos_func_np", cos_func_np, METH_VARARGS, "evaluate the cosine on a numpy array"}, {NULL, NULL, 0, NULL} };
/* module initialization */ PyMODINIT_FUNC
initcos_module_np(void) { (void) Py_InitModule("cos_module_np", CosMethods); /* IMPORTANT: this must be called */ import_array(); }
""" Example of wrapping cos function from math.h using ctypes. """
import ctypes from ctypes.util import find_library
# find and load the library libm = ctypes.cdll.LoadLibrary(find_library('m')) # set the argument type libm.cos.argtypes = [ctypes.c_double] # set the return type libm.cos.restype = ctypes.c_double
defcos_func(arg): ''' Wrapper for cos from math.h ''' return libm.cos(arg)
In [4]: cos_module.cos_func(1.0) Out[4]: 0.5403023058681398
In [5]: cos_module.cos_func(0.0) Out[5]: 1.0
In [6]: cos_module.cos_func(3.14159265359) Out[6]: -1.0
正如之前的例子,这个代码稍微健壮一些。尽管错误信息不怎么有用,因它并没告诉我们应该是什么类型。
1 2 3 4 5 6 7 8 9 10 11 12
In [7]: cos_module.cos_func('foo') --------------------------------------------------------------------------- ArgumentError Traceback (most recent call last) <ipython-input-7-11bee483665d> in <module>() ----> 1 cos_module.cos_func('foo')
/home/esc/git-working/scipy-lecture-notes/advanced/interfacing_with_c/ctypes/cos_module.py in cos_func(arg) 12 def cos_func(arg): 13 ''' Wrapper for cos from math.h ''' ---> 14 return libm.cos(arg)
ArgumentError: argument 1: <type 'exceptions.TypeError'>: wrong type
voidcos_doubles(double * in_array, double * out_array, int size);
这个实现在C源码中如下:
1 2 3 4 5 6 7 8 9 10
#include<math.h>
/* Compute the cosine of each element in in_array, storing the result in * out_array. */ voidcos_doubles(double * in_array, double * out_array, int size){ int i; for(i=0;i<size;i++){ out_array[i] = cos(in_array[i]); } }
""" Example of wrapping a C library function that accepts a C double array as input using the numpy.ctypeslib. """
import numpy as np import numpy.ctypeslib as npct from ctypes import c_int
# input type for the cos_doubles function # must be a double array, with single dimension that is contiguous array_1d_double = npct.ndpointer(dtype=np.double, ndim=1, flags='CONTIGUOUS')
# load the library, using numpy mechanisms libcd = npct.load_library("libcos_doubles", ".")
# setup the return typs and argument types libcd.cos_doubles.restype = None libcd.cos_doubles.argtypes = [array_1d_double, array_1d_double, c_int]
/* Example of wrapping cos function from math.h using SWIG. */
%module cos_module %{ /* the resulting C file should be built as a python extension */ #define SWIG_FILE_WITH_INIT /* Includes the header in the wrapper code */ #include"cos_module.h" %} /* Parse the header file to generate wrappers */ %include "cos_module.h"
voidcos_doubles(double * in_array, double * out_array, int size);
1 2 3 4 5 6 7 8 9 10
#include <math.h>
/* Compute the cosine of each element in in_array, storing the result in * out_array. */ void cos_doubles(double * in_array, double * out_array, int size){ int i; for(i=0;i<size;i++){ out_array[i] = cos(in_array[i]); } }
/* Example of wrapping a C function that takes a C double array as input using * numpy typemaps for SWIG. */
%module cos_doubles %{ /* the resulting C file should be built as a python extension */ #define SWIG_FILE_WITH_INIT /* Includes the header in the wrapper code */ #include"cos_doubles.h" %}
/* include the numpy typemaps */ %include "numpy.i" /* need this for correct module initialization */ %init %{ import_array(); %}
/* typemaps for the two arrays, the second will be modified in-place */ %apply (double* IN_ARRAY1, int DIM1) {(double * in_array, int size_in)} %apply (double* INPLACE_ARRAY1, int DIM1) {(double * out_array, int size_out)}
/* Wrapper for cos_doubles that massages the types */ %inline %{ /* takes as input two numpy arrays */ voidcos_doubles_func(double * in_array, int size_in, double * out_array, int size_out){ /* calls the original funcion, providing only the size of the first */ cos_doubles(in_array, out_array, size_in); } %}
voidcos_doubles(double * in_array, double * out_array, int size);
1 2 3 4 5 6 7 8 9 10
#include<math.h>
/* Compute the cosine of each element in in_array, storing the result in * out_array. */ voidcos_doubles(double * in_array, double * out_array, int size){ int i; for(i=0;i<size;i++){ out_array[i] = cos(in_array[i]); } }
To follow the path:(沿着这样一条道路:) look to the master,(寻找大师,) follow the master,(跟随大师,) walk with the master,(与大师通行,) see through the master,(洞察大师,) become the master.(成为大师。)
You can’t connect the dots looking forward you can only connect them looking backwards. So you have to trust that the dots will somehow connect in your future. You have to trust in something: your gut, destiny, life, karma, whatever. Because believing that the dots will connect down the road will give you the confidence to follow your heart, even when it leads you off the well worn path.
>>> nums = [1,2,3] # note that ... varies: these are different objects >>> iter(nums) <listiterator object at ...> >>> nums.__iter__() <listiterator object at ...> >>> nums.__reversed__() <listreverseiterator object at ...>
>>> import itertools >>> defg(): ... print'--start--' ... for i in itertools.count(): ... print'--yielding %i--' % i ... try: ... ans = yield i ... except GeneratorExit: ... print'--closing--' ... raise ... except Exception as e: ... print'--yield raised %r--' % e ... else: ... print'--yield returned %s--' % ans
>>> defdecorator_with_arguments(arg): ... print"defining the decorator" ... def_decorator(function): ... # in this inner function, arg is available too ... print"doing decoration,", arg ... return function ... return _decorator >>> @decorator_with_arguments("abc") ... deffunction(): ... print"inside function" defining the decorator doing decoration, abc >>> function() inside function
>>> classdecorator_class(object): ... def__init__(self, arg): ... # this method is called in the decorator expression ... print"in decorator init,", arg ... self.arg = arg ... def__call__(self, function): ... # this method is called to do the job ... print"in decorator call,", self.arg ... return function >>> deco_instance = decorator_class('foo') in decorator init, foo >>> @deco_instance ... deffunction(*args, **kwargs): ... print"in function,", args, kwargs in decorator call, foo >>> function() in function, () {}
classassert_raises(object): # based on pytest and unittest.TestCase def__init__(self, type): self.type = type def__enter__(self): pass def__exit__(self, type, value, traceback): if type isNone: raise AssertionError('exception expected') if issubclass(type, self.type): returnTrue# swallow the expected exception raise AssertionError('wrong exception type')
在ctags的例子中,我们没告诉Portage有关任何依赖。当情况是这样时,没关系,因为ctags仅仅需要一个基本的工具链来编译和运行(参见Implicit System Dependency理解为何我们不需要显式依赖)。然而事情很少这么简单。
这是app-misc/detox/detox-1.1.1.ebuild:
# Copyright 1999-2012 Gentoo Foundation# Distributed under the terms of the GNU General Public License v2# $Header: $EAPI=4DESCRIPTION="detox safely removes spaces and strange characters from filenames"HOMEPAGE="http://detox.sourceforge.net/"SRC_URI="mirror://sourceforge/${PN}/${P}.tar.bz2"LICENSE="BSD"SLOT="0"KEYWORDS="~hppa ~mips sparc x86"RDEPEND="dev-libs/popt"DEPEND="${RDEPEND}
sys-devel/flex
sys-devel/bison"
src_configure() {
econf --with-popt
}
src_install() {
emake DESTDIR="${D}" install
dodoc README CHANGES
}
# Copyright 1999-2012 Gentoo Foundation# Distributed under the terms of the GNU General Public License v2# $Header: $
EAPI=4
inherit eutils
DESCRIPTION="detox safely removes spaces and strange characters from filenames"
HOMEPAGE="http://detox.sourceforge.net/"
SRC_URI="mirror://sourceforge/${PN}/${P}.tar.bz2"
LICENSE="BSD"
SLOT="0"
KEYWORDS="~hppa ~mips ~sparc ~x86"
RDEPEND="dev-libs/popt"
DEPEND="${RDEPEND}
sys-devel/flex
sys-devel/bison"src_prepare() {
epatch "${FILESDIR}"/${P}-destdir.patch \
"${FILESDIR}"/${P}-parallel_build.patch
}
src_configure() {
econf --with-popt
}
src_install() {
emake DESTDIR="${D}" install
dodoc README CHANGES
}
注意${FILESDIR}/${P}-destdir.patch指向detox-1.1.0-destdir.patch,这个文件在Portage树的files/子文件夹中。更大的补丁文件必须在你的开发者空间dev.gentoo.org而不是files/或镜像中——参见Gentoo Mirrors和Patching with epatch。
# Copyright 1999-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: $
EAPI=4
DESCRIPTION="GNU charset conversion library for libc which doesn't implement it"HOMEPAGE="http://www.gnu.org/software/libiconv/"SRC_URI="ftp://ftp.gnu.org/pub/gnu/libiconv/${P}.tar.gz"
LICENSE="LGPL-2.1"SLOT="0"KEYWORDS="~amd64 ~ppc ~sparc ~x86"IUSE="nls"
DEPEND="!sys-libs/glibc"
src_configure() {
econf $(use_enable nls)
}
src_install() {
emake DESTDIR="${D}" install
}